函式
<new>

operator new

throwing (1)
void* operator new (std::size_t size) throw (std::bad_alloc);
nothrow (2)
void* operator new (std::size_t size, const std::nothrow_t& nothrow_value) throw();
placement (3)
void* operator new (std::size_t size, void* ptr) throw();
throwing (1)
void* operator new (std::size_t size);
nothrow (2)
void* operator new (std::size_t size, const std::nothrow_t& nothrow_value) noexcept;
placement (3)
void* operator new (std::size_t size, void* ptr) noexcept;
分配儲存空間
預設的分配函式(單物件形式)。

(1)丟擲異常的分配
分配 size 位元組的儲存空間,該空間對任何大小的物件都具有合適的對齊方式,並返回指向此塊記憶體第一個位元組的非空指標。
失敗時,它會丟擲 bad_alloc 異常。
(2)不丟擲異常的分配
與上面(1)相同,不同之處在於失敗時返回空指標而不是丟擲異常。
如果被替換,第一種和第二種版本都應返回具有相同屬性的指標。
預設定義透過呼叫第一個版本來分配記憶體:::operator new (size)
如果被替換,第一種和第二種版本都應返回具有相同屬性的指標。
(3)定位
簡單地返回 ptr(不分配任何儲存空間)。
但請注意,如果該函式是由new表示式呼叫的,則會執行正確的初始化(對於類物件,這包括呼叫其預設建構函式)。

預設的分配和釋放函式是標準庫的特殊元件;它們具有以下獨特屬性:
  • 全域性:operator new 的所有三個版本都在全域性名稱空間中宣告,而不是在 std 名稱空間中。
  • 隱式:分配版本((1)(2))在 C++ 程式的每個翻譯單元中都隱式宣告,無論是否包含標頭檔案 <new>
  • 可替換:分配版本((1)(2))也可替換:程式可以提供自己的定義來替換預設提供的定義,以產生上述結果,或者可以為特定型別過載它。

如果已使用 set_new_handler 定義了 new_handler 函式,則當分配版本((1)(2))無法分配所需儲存空間時,將由這些分配版本的預設定義呼叫此new-handler 函式。

operator new 可以顯式地作為一個常規函式呼叫,但在 C++ 中,new 是一個具有非常特定行為的運算子:帶有 new 運算子的表示式首先用其型別說明符的大小作為第一個引數呼叫函式 operator new(即此函式),如果成功,則自動初始化或構造物件(如果需要)。最後,該表示式求值為指向相應型別的指標。

引數

size
請求記憶體塊的大小(以位元組為單位)。
當由new表示式自動呼叫時,這是型別說明符的大小。
如果此引數為零,則函式成功時仍返回一個不同的非空指標(儘管解引用此指標會導致未定義行為)。
size_t 是一個整型。
nothrow_value
常量 nothrow
此引數僅用於將其與具有過載版本的第一個版本區分開。當 nothrow 常量作為第二個引數傳遞給 operator new 時,operator new 在失敗時返回空指標,而不是丟擲 bad_alloc 異常。
nothrow_t 是常量 nothrow 的型別。
ptr
指向已分配的、大小合適的記憶體塊的指標。
如果由new表示式呼叫,則在該位置初始化(或構造)物件。

返回值

對於第一和第二個版本,指向新分配的儲存空間的指標。
對於第三個版本,返回 ptr

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// operator new example
#include <iostream>     // std::cout
#include <new>          // ::operator new

struct MyClass {
  int data[100];
  MyClass() {std::cout << "constructed [" << this << "]\n";}
};

int main () {

  std::cout << "1: ";
  MyClass * p1 = new MyClass;
      // allocates memory by calling: operator new (sizeof(MyClass))
      // and then constructs an object at the newly allocated space

  std::cout << "2: ";
  MyClass * p2 = new (std::nothrow) MyClass;
      // allocates memory by calling: operator new (sizeof(MyClass),std::nothrow)
      // and then constructs an object at the newly allocated space

  std::cout << "3: ";
  new (p2) MyClass;
      // does not allocate memory -- calls: operator new (sizeof(MyClass),p2)
      // but constructs an object at p2

  // Notice though that calling this function directly does not construct an object:
  std::cout << "4: ";
  MyClass * p3 = (MyClass*) ::operator new (sizeof(MyClass));
      // allocates memory by calling: operator new (sizeof(MyClass))
      // but does not call MyClass's constructor

  delete p1;
  delete p2;
  delete p3;

  return 0;
}

可能的輸出

1: constructed [0x8f0f70]
2: constructed [0x8f23a8]
3: constructed [0x8f23a8]
4: 


資料競爭

修改返回的值所引用的儲存。
分配和釋放函式的呼叫,如果重用了相同的儲存單元,則應以單一的總順序進行,其中每次釋放都完全發生在下次分配之前。
這也應適用於此函式的自定義替換的可觀察行為。

異常安全

第一個版本(1) 在無法分配儲存空間時丟擲 bad_alloc
否則,它不丟擲任何異常(無異常保證)。

另見